/*
 * @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
 * @Date: 2024-05-02 23:32:06
 * @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
 * @LastEditTime: 2024-05-28 17:14:36
 * @FilePath: /hw/110/pipe/Shm_ipc/Comm.hpp
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#pragma once
#include<iostream>
#include<stdio.h>
#include<sys/ipc.h>
#include <sys/types.h>
#include<cstring>
#include<cerrno>
#include<stdlib.h>
#include<sys/shm.h>

using namespace std;

//定义一个路径和pro_id
const char *pathname="/home/hw/110";
int pro_id=0x666;
const int defaultsize=4096;

//获取唯一key值
key_t GetShmKey()
{
    key_t key;
    key=ftok(pathname,pro_id);
    if(key<0)
    {
       // cout<<"ftok error"<<errno<<endl;
        std::cerr << "ftok error, errno : " << errno << ", error string: " << strerror(errno) << std::endl;
        exit(1);
    }
    return key;
}

//转化为十六进制表示，因为os中大多数都是十六进制表示
string Tohex(key_t x)
{
    char buffer[1024];
    snprintf(buffer,sizeof(buffer),"0x%x",x);
    return buffer;
}

//很多情况需要shmid
int CreateShmOrDie(key_t key,int size,int flag)
{
    int shmid=shmget(key,size,flag);
    if(shmid<0)
    {
        std::cerr << "shmid error, errno : " << errno << ", error string: " << strerror(errno) << std::endl;
        exit(2);
    }
    return shmid;
}
int CreateShm(key_t key,int size)
{
    //IPC_CREAT 不存在就创建
    //IPC_EXCL  没有意义
    //IPC_CREAT|IPC_EXCL 不存在就创建，存在就错误返回
    return CreateShmOrDie(key,size,IPC_CREAT|IPC_EXCL|0666);
}
int GetShm(key_t key,int size)
{
    return CreateShmOrDie(key,size,IPC_CREAT);
}
void DelShm(int shmid)
{
    int n=shmctl(shmid,IPC_RMID,nullptr);
    if(n<0)
    {
       std::cerr << "DelShm error, errno : " << errno << ", error string: " << strerror(errno) << std::endl;
       exit(3);
    }
    std::cout << "shmctl delete shm success, shmid: " << shmid << std::endl;

}
void ShmDebug(int shmid)
{
    struct shmid_ds shmds;
    int n=shmctl(shmid,IPC_STAT,&shmds);
    if(n<0)
    {
        std::cerr << "shmid error " << std::endl;
        return ;
    }
    cout<<"shmds.shm_cpid:"<<Tohex(shmds.shm_cpid)<<endl;
    cout<<"shmds.shm_ctime:"<<shmds.shm_ctime<<endl;
    

}
void *ShmAttach(int shmid)
{
    char *addr=(char*)shmat(shmid,nullptr,0);
    if((long long int)addr==-1)
    {
        cerr<<"shmat error"<<endl;
        return nullptr;
    }
    return addr;
}
void  Detach(void *addr)
{
    int n=shmdt(addr);
    if(n<0)
    {
        cerr<<"shmdt error"<<endl;
        return ;
    }
    
}